package com.binarysoft.service.common.snmp;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;

import common.framework.dsb.client.DefaultServiceFactory;
import common.framework.dsb.client.ServiceFactory;

public class UnitTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {

		Set<SnmpObject> objects = new LinkedHashSet<SnmpObject>();

		SnmpObject o1 = new SnmpObject();
		o1.setName("ifDescr");
		o1.setOid("1.3.6.1.2.1.2.2.1.2");
		o1.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o1);

		SnmpObject o2 = new SnmpObject();
		o2.setName("sysDescr");
		o2.setOid("1.3.6.1.2.1.1.1");
		o2.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o2);

		SnmpObject o3 = new SnmpObject();
		o3.setName("sysObjectID");
		o3.setOid("1.3.6.1.2.1.1.2");
		o3.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o3);

		SnmpObject o4 = new SnmpObject();
		o4.setName("ifSpeed");
		o4.setOid("1.3.6.1.2.1.2.2.1.5");
		o4.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o4.setIndexObject(o1);
		objects.add(o4);

		SnmpObject o5 = new SnmpObject();
		o5.setName("ifType");
		o5.setOid("1.3.6.1.2.1.2.2.1.3");
		o5.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o5.setIndexObject(o1);
		objects.add(o5);

		SnmpObject o6 = new SnmpObject();
		o6.setName("ipAdEntIfIndex");
		o6.setOid("1.3.6.1.2.1.4.20.1.2");
		o6.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		//o6.setIndexObject(o1);
		objects.add(o6);

		
		SnmpObject o7 = new SnmpObject();
		o7.setName("hrStorageSize");
		o7.setOid("1.3.6.1.2.1.25.2.3.1.5");
		o7.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		//o6.setIndexObject(o1);
		objects.add(o7);
		
		SnmpTarget snmpTarget = new SnmpTarget();

		snmpTarget.setSnmpVersion(SnmpService.VERSION2C);
		// snmpTarget.setSnmpVersion(SnmpService.VERSION2C);
		snmpTarget.setReadCommunity("public");

		snmpTarget.setHostAddress("10.4.246.142");
		snmpTarget.setSnmpPort(161);
		String serviceName = "DSB/SnmpService";
		int port = 10000;

		ServiceFactory serviceFatory = new DefaultServiceFactory();
		SnmpService snmpService = serviceFatory.lookup(serviceName, "localhost", port);
		SnmpResult result = snmpService.snmpGet(objects, snmpTarget);

		print(result);
	}

	public static SnmpResult remoteCallTest(String hostAddress) throws Exception {
		SnmpTarget snmpTarget = new SnmpTarget();
		// V3
		snmpTarget.setSnmpVersion(SnmpService.VERSION3);
		snmpTarget.setSecurityLevel(SnmpService.AUTH_PRIV);
		snmpTarget.setAuthProtocol(SnmpService.AUTH_MD5);
		snmpTarget.setAuthPassword("authPass");
		snmpTarget.setPrivProtocol(SnmpService.PRIV_DES);
		snmpTarget.setPrivatePassword("privPass");
		snmpTarget.setContextName("privContext");
		snmpTarget.setUserName("userName");

		// // V1/2
		// snmpTarget.setSnmpVersion(SnmpService.VERSION2C);
		// snmpTarget.setReadCommunity("public");

		snmpTarget.setHostAddress("132.159.156.147");
		snmpTarget.setSnmpPort(161);
		String serviceName = "DSB/SnmpService";
		int port = 10000;

		ServiceFactory serviceFatory = new DefaultServiceFactory();
		SnmpService snmpService = (SnmpService) serviceFatory.lookup(serviceName, hostAddress, port);
		Collection<SnmpObject> objects = createObjects();
		return snmpService.snmpGet(objects, snmpTarget);
	}

	public static Collection<SnmpObject> createObjects() {
		Set<SnmpObject> objects = new LinkedHashSet<SnmpObject>();

		SnmpObject o1 = new SnmpObject();
		o1.setName("sysDescr");
		o1.setOid("1.3.6.1.2.1.1.1.0");
		o1.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o1);

		SnmpObject o2 = new SnmpObject();
		o2.setName("sysObjectID");
		o2.setOid("1.3.6.1.2.1.1.2.0");
		o2.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o2);

		SnmpObject o3 = new SnmpObject();
		o3.setName("sysUpTime");
		o3.setOid("1.3.6.1.2.1.1.3.0");
		o3.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o3);

		SnmpObject o4 = new SnmpObject();
		o4.setName("sysContact");
		o4.setOid("1.3.6.1.2.1.1.4.0");
		o4.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o4);

		SnmpObject o5 = new SnmpObject();
		o5.setName("sysName");
		o5.setOid("1.3.6.1.2.1.1.5.0");
		o5.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o5);

		SnmpObject o6 = new SnmpObject();
		o6.setName("sysLocation");
		o6.setOid("1.3.6.1.2.1.1.6.0");
		o6.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o6);

		SnmpObject o7 = new SnmpObject();
		o7.setName("sysServices");
		o7.setOid("1.3.6.1.2.1.1.7.0");
		o7.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o7);

		SnmpObject o8 = new SnmpObject();
		o8.setName("ifIndex");
		o8.setOid("1.3.6.1.2.1.2.2.1.1");
		o8.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		// objects.add(o8);

		SnmpObject o9 = new SnmpObject();
		o9.setName("udpLocalPort");
		o9.setOid("1.3.6.1.2.1.7.5.1.2");
		o9.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o9);

		SnmpObject o10 = new SnmpObject();
		o10.setName("ipAdEntAddr");
		o10.setOid("1.3.6.1.2.1.4.20.1.1");
		o10.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o10);

		SnmpObject o11 = new SnmpObject();
		o11.setName("ifInOctets");
		o11.setOid("1.3.6.1.2.1.2.2.1.10");
		o11.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o11.setIndexObject(o8);
		objects.add(o11);

		SnmpObject o12 = new SnmpObject();
		o12.setName("ifOutOctets");
		o12.setOid("1.3.6.1.2.1.2.2.1.16");
		o12.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o12.setIndexObject(o8);
		objects.add(o12);

		SnmpObject o13 = new SnmpObject();
		o13.setName("ifDescr");
		o13.setOid("1.3.6.1.2.1.2.2.1.2");
		o13.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o13.setIndexObject(o8);
		objects.add(o13);
		return objects;
	}

	public static void testLocal() throws Exception {
		// TODO Auto-generated method stub
		TransportMapping transportMapping = new DefaultUdpTransportMapping();
		Snmp snmp = new Snmp(transportMapping);
		transportMapping.listen();

		SnmpTarget snmpTarget = new SnmpTarget();
		snmpTarget.setSnmpVersion(SnmpService.VERSION2C);
		snmpTarget.setHostAddress("132.159.156.190");
		snmpTarget.setSnmpPort(161);
		snmpTarget.setReadCommunity("public");

		CommunityTarget target = new CommunityTarget();
		target.setVersion(snmpTarget.getSnmpVersion());
		target.setCommunity(new OctetString(snmpTarget.getReadCommunity()));
		target.setRetries(3);
		target.setTimeout(5000);
		target.setAddress(GenericAddress.parse("udp:" + snmpTarget.getHostAddress() + "/" + snmpTarget.getSnmpPort()));

		OID oid = new OID(".1.3.6.1.2.1.1.2.0");
		PDU pdu = DefaultPDUFactory.createPDU(target, PDU.GET);
		pdu.add(new VariableBinding(oid));
		ResponseEvent respones = snmp.send(pdu, target);
		System.out.println(respones.getResponse().get(0));
	}

	public static SnmpResult testCollect(SnmpTarget snmpTarget, Snmp snmp) throws AbortException {
		return SnmpTool.collect(snmpTarget, snmp, createObjects(), 5);
	}

	public static SnmpResult testType1(SnmpTarget snmpTarget, Snmp snmp) throws AbortException {
		Set<SnmpObject> objects = new LinkedHashSet<SnmpObject>();
		SnmpObject o1 = new SnmpObject();
		o1.setName("sysDescr");
		o1.setOid("1.3.6.1.2.1.1.1");
		o1.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o1);

		SnmpObject o2 = new SnmpObject();
		o2.setName("sysObjectID");
		o2.setOid("1.3.6.1.2.1.1.2");
		o2.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o2);

		SnmpObject o3 = new SnmpObject();
		o3.setName("sysUpTime");
		o3.setOid("1.3.6.1.2.1.1.3");
		o3.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o3);

		SnmpObject o4 = new SnmpObject();
		o4.setName("sysContact");
		o4.setOid("1.3.6.1.2.1.1.4");
		o4.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o4);

		SnmpObject o5 = new SnmpObject();
		o5.setName("sysName");
		o5.setOid("1.3.6.1.2.1.1.5");
		o5.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o5);

		SnmpObject o6 = new SnmpObject();
		o6.setName("sysLocation");
		o6.setOid("1.3.6.1.2.1.1.6");
		o6.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o6);

		SnmpObject o7 = new SnmpObject();
		o7.setName("sysServices");
		o7.setOid("1.3.6.1.2.1.1.7");
		o7.setObjectType(SnmpService.SINGLE_INSTANCE_OBJECT);
		objects.add(o7);

		SnmpResult snmpResult = new DefaultSnmpResult();

		SnmpTool.type1collect(objects, 5, snmpTarget, snmp, snmpResult);

		return snmpResult;

	}

	public static SnmpResult testType2(SnmpTarget snmpTarget, Snmp snmp) throws AbortException {
		Set<SnmpObject> objects = new LinkedHashSet<SnmpObject>();
		SnmpObject o1 = new SnmpObject();
		o1.setName("ifIndex");
		o1.setOid("1.3.6.1.2.1.2.2.1.1");
		o1.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o1);

		SnmpObject o2 = new SnmpObject();
		o2.setName("udpLocalPort");
		o2.setOid("1.3.6.1.2.1.7.5.1.2");
		o2.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o2);

		SnmpObject o3 = new SnmpObject();
		o3.setName("ipAdEntAddr");
		o3.setOid("1.3.6.1.2.1.4.20.1.1");
		o3.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(o3);

		SnmpResult snmpResult = new DefaultSnmpResult();
		SnmpTool.type2collect(objects, snmpTarget, snmp, snmpResult);
		return snmpResult;
	}

	public static SnmpResult testType3(SnmpTarget snmpTarget, Snmp snmp) throws AbortException {
		SnmpResult snmpResult = new DefaultSnmpResult();

		Set<SnmpObject> objects = new LinkedHashSet<SnmpObject>();

		SnmpObject index = new SnmpObject();
		index.setName("ifIndex");
		index.setOid("1.3.6.1.2.1.2.2.1.1");
		index.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITHOUT_INDEX);
		objects.add(index);
		SnmpTool.type2collect(objects, snmpTarget, snmp, snmpResult);

		SnmpObject o1 = new SnmpObject();
		o1.setName("ifDescr");
		o1.setOid("1.3.6.1.2.1.2.2.1.2");
		o1.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o1.setIndexObject(index);
		objects.add(o1);

		SnmpObject o2 = new SnmpObject();
		o2.setName("ifInOctets");
		o2.setOid("1.3.6.1.2.1.2.2.1.10");
		o2.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o2.setIndexObject(index);
		objects.add(o2);

		SnmpObject o3 = new SnmpObject();
		o3.setName("ifOutOctets");
		o3.setOid("1.3.6.1.2.1.2.2.1.16");
		o3.setObjectType(SnmpService.MULTI_INSTANCE_OBJECT_WITH_INDEX);
		o3.setIndexObject(index);
		objects.add(o3);

		SnmpTool.type3collect(objects, 5, snmpTarget, snmp, snmpResult);
		return snmpResult;
	}

	public static void print(SnmpResult snmpResult) {
		Collection<SnmpValue> values = snmpResult.getValues();
		Iterator<SnmpValue> iter = values.iterator();
		while (iter.hasNext()) {
			SnmpValue sv = iter.next();
			System.out.println(sv.getObjectName() + "." + sv.getIndex() + "=" + sv.getValue());
		}
	}
}
